package org.haptimap.hcimodules.tactilecompass;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class TactileCompassView extends View implements BearingModuleListener {

	// ========================================================================
	// Constant Fields
	// ========================================================================

	protected static final String	TAG	= "TactileCompassView";

	// ========================================================================
	// Fields
	// ========================================================================

	private Rect					bounds;
	private Paint					textPaint;

	private TactileCompass			tactileCompass;

	private Resources				resources;
	private Drawable				compassBackgroundVibEnabledIcon;
	private Drawable				compassBackgroundVibDisabledIcon;
	private Drawable				compassNeedleIcon;
	private Drawable				compassNeedleHighlightedIcon;

	private Rect					compassBackgroundBounds;
	private Rect					compassNeedleBounds;
	private Point					compassNeedlePivotPoint;

	// private boolean vibrationEnabled;

	// ========================================================================
	// Constructor
	// ========================================================================

	public TactileCompassView(Context context) {
		super(context);
		this.init(context);
	}

	public TactileCompassView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.init(context);
	}

	public TactileCompassView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.init(context);
	}

	private void init(Context context) {

		this.bounds = new Rect();
		this.compassNeedleBounds = new Rect();
		this.compassBackgroundBounds = new Rect();
		this.compassNeedlePivotPoint = new Point();

		int color = Color.parseColor("#222222");
		int textSize = 20;

		this.textPaint = new Paint();
		this.textPaint.setColor(color);
		this.textPaint.setTextSize(textSize);

		this.resources = context.getResources();
	}

	// ========================================================================
	// Methods
	// ========================================================================

	public void init(TactileCompass tactileCompass,
			int compassBackgroundVibEnabledId,
			int compassBackgroundVibDisabledId,
			int compassNeedleId,
			int compassNeedleHighlightedId) {

		this.tactileCompass = tactileCompass;
		this.compassBackgroundVibEnabledIcon = resources
				.getDrawable(compassBackgroundVibEnabledId);
		this.compassBackgroundVibDisabledIcon = resources
				.getDrawable(compassBackgroundVibDisabledId);
		this.compassNeedleIcon = resources.getDrawable(compassNeedleId);
		this.compassNeedleHighlightedIcon = resources
				.getDrawable(compassNeedleHighlightedId);

		this.tactileCompass.getBearingModule().addListener(this);
	}

	// ------------------------------------------------------------------------
	// Implementation of 'View'
	// ------------------------------------------------------------------------

	@Override
	protected void onLayout(boolean changed,
			int left,
			int top,
			int right,
			int bottom) {
		if (changed) {
			this.bounds.set(left, top, right, bottom);

			int w = right - left;
			int h = bottom - top;

			this.compassBackgroundBounds.set(0, 0, w, h);

			int nw = w / 20;
			int margin = 20;
			this.compassNeedleBounds.set(w / 2 - nw, margin, w / 2 + nw, h
					- margin);
			this.compassNeedlePivotPoint.set(w / 2, h / 2);

			this.invalidate();
		}
	}

	@Override
	public void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		if (tactileCompass == null
				|| compassBackgroundVibDisabledIcon == null
				|| compassBackgroundVibEnabledIcon == null
				|| compassNeedleIcon == null
				|| compassNeedleHighlightedIcon == null) {
			Log
					.e(
							TAG,
							"TactileCompassView is not initialised. Call init(TactileCompass, ...) first");
			return;
		}

		if (this.tactileCompass.getBearingModule().hasDestination()) {

			// draw background
			if (!tactileCompass.isMuted()) {
				this.compassBackgroundVibEnabledIcon
						.setBounds(this.compassBackgroundBounds);
				this.compassBackgroundVibEnabledIcon.draw(canvas);
			} else {
				this.compassBackgroundVibDisabledIcon
						.setBounds(this.compassBackgroundBounds);
				this.compassBackgroundVibDisabledIcon.draw(canvas);
			}

			// draw foreground
			canvas.rotate(
					this.tactileCompass
							.getBearingModule()
							.getRelativeDirection(),
					this.compassNeedlePivotPoint.x,
					this.compassNeedlePivotPoint.y);

			if (this.tactileCompass
					.getBearingModule()
					.getHeadingModule()
					.isUsingPointingDirection()) {
				this.compassNeedleHighlightedIcon
						.setBounds(this.compassNeedleBounds);
				this.compassNeedleHighlightedIcon.draw(canvas);
			} else {
				this.compassNeedleIcon.setBounds(this.compassNeedleBounds);
				this.compassNeedleIcon.draw(canvas);
			}
		}
	}

	@SuppressWarnings("unused")
	private void drawDistanceInfo(Canvas canvas, String text) {

		final float textWidth = textPaint.measureText(text);
		final float halfTextWidth = textWidth / 2;
		final float x = this.getWidth() / 2 - halfTextWidth;
		final float y = this.getHeight();

		canvas.drawText(text, x, y, textPaint);
	}

	// ------------------------------------------------------------------------
	// Implementation of 'BearingModuleListener'
	// ------------------------------------------------------------------------

	public void onBearingChanged() {
		this.postInvalidate();
	}

	public void onStartScanningMode() {
		this.postInvalidate();
	}
}
